#ifndef SYNC_H
#define SYNC_H

#include <stdint.h>
#include "scheduler.h"

// ===== 自旋锁(Spinlock) =====

typedef struct {
    volatile int locked;      // 锁状态: 0=未锁定, 1=已锁定
    const char* name;         // 锁名称(用于调试)
    uint32_t cpu_id;          // 持有锁的CPU ID
} spinlock_t;

/**
 * 初始化自旋锁
 */
void spinlock_init(spinlock_t* lk, const char* name);

/**
 * 获取自旋锁(会关闭中断)
 */
void spinlock_acquire(spinlock_t* lk);

/**
 * 释放自旋锁(恢复中断)
 */
void spinlock_release(spinlock_t* lk);

/**
 * 检查当前CPU是否持有锁
 */
int holding(spinlock_t* lk);


// ===== 睡眠锁(Sleep Lock) =====

typedef struct {
    spinlock_t lk;            // 保护睡眠锁的自旋锁
    volatile int locked;      // 睡眠锁状态
    const char* name;         // 锁名称
    uint32_t pid;             // 持有锁的进程PID
} sleeplock_t;

/**
 * 初始化睡眠锁
 */
void sleeplock_init(sleeplock_t* lk, const char* name);

/**
 * 获取睡眠锁(会睡眠等待)
 */
void sleeplock_acquire(sleeplock_t* lk);

/**
 * 释放睡眠锁
 */
void sleeplock_release(sleeplock_t* lk);

/**
 * 检查当前进程是否持有睡眠锁
 */
int holdingsleep(sleeplock_t* lk);


// ===== 条件变量(基于sleep/wakeup) =====

typedef struct {
    void* channel;            // 等待通道
    const char* name;         // 条件变量名称
} condvar_t;

/**
 * 初始化条件变量
 */
void condvar_init(condvar_t* cv, const char* name);

/**
 * 等待条件变量(必须持有锁lk)
 * 原子地释放锁lk并进入睡眠,唤醒后重新获取锁
 */
void condvar_wait(condvar_t* cv, spinlock_t* lk);

/**
 * 唤醒等待在条件变量上的一个进程
 */
void condvar_signal(condvar_t* cv);

/**
 * 唤醒等待在条件变量上的所有进程
 */
void condvar_broadcast(condvar_t* cv);


// ===== 信号量(Semaphore) =====

typedef struct {
    int value;                // 信号量值
    spinlock_t lk;            // 保护信号量的锁
    const char* name;         // 信号量名称
} semaphore_t;

/**
 * 初始化信号量
 */
void semaphore_init(semaphore_t* sem, int value, const char* name);

/**
 * P操作(减1,可能阻塞)
 */
void semaphore_down(semaphore_t* sem);

/**
 * V操作(加1,唤醒等待进程)
 */
void semaphore_up(semaphore_t* sem);

#endif // SYNC_H

